#ifndef APP_H
#define APP_H

// ###########################################################################################################################################
// MODELO DO RECURSOS DE HARDAWARES
#define MODEL			"hr01"
#define FIRMWARE_VERSION "1.0"
#define PROGAM_NAME "examples " MODEL " firmware v" FIRMWARE_VERSION " [compiled in " __DATE__ " " __TIME__ "]" CMD_TERMINATOR

#define LOG_APP				pdOFF

// ###########################################################################################################################################
// INCLUDES OBRIGATÓRIAS
#include "_config_cpu_.h"
#include "error.h"
#include "iap.h"
#include "crc.h"
#include "stdio_uc.h"
#include "systick.h"
#include "delay.h"
#include "led_error.h"
#include "beep.h"
#include "gkey.h"
#include "liquid_crystal.h"
#include "servus.h"
#include "joyps.h"

// ###########################################################################################################################################
// SERVOS
typedef struct {
	volatile uint timeActiveCount; 	// Tempo em segundos do contator para timeActiveOff
	volatile uint timeActiveOff; 	// Tempo em segundos que o servo ficará ligado. Valor 0 sinaliza ligado direto
	volatile uint countProgress;	// Tempo em ms de progressão. valor > 0 quando o servo receber uma nova posição ele vai progressiva em ms para aquela posição, senão vai imediatamente
	volatile uint time; 			// Tenpo para controle do modo progressivo
	uint pos; 						// posição para atualizar o servos
	uint posNew; 					// nova posição para o servo ir
	#define nPAR_SERVO 	6
	s32 par[nPAR_SERVO]; 			// Parametros de trabalho do relé.
		#define minSERVO_US 100
		#define maxSERVO_US 3000
		#define minOFFSET_US -1500
		#define maxOFFSET_US 1500
		#define minTIME_PROGRESS 0
		#define maxTIME_PROGRESS 500
		#define minTIME_OFF 0
		#define maxTIME_OFF 500
} tServos;

// Mascarando o buffer de par de trabalho para acesso fácil
// Mascara de trabalho para os parâmetros do relé
typedef struct {
	s32 offset;
	s32 init;
	s32 min;
	s32 max;
	s32 timeActiveOff;
	s32 timeProgress;
} tParServo;

// ###########################################################################################################################################
// RELAYS
typedef struct {
	int st; // estado dp rele
	volatile uint timeout; // contagem de tempo em ms para voltar ao estado anterior do rele
} tRelay, *pRelay;


// ###########################################################################################
// ESTRUTURA DA FLASH DE DADOS

// SETOR 14 da FLASH addr 0x0000e000
#define lenFLASH_LOG 256
#define nLOG 30

	// countTick slot 0		4
	// code slot 0			1
	// countTick slot1		4
	// code slot 1			1
	// countTick slot2		4
	// code slot 2			1

	//---------------------------------------------
	// 	TOTAL REQUERIDO = 150 bytes
	//	Tamanho do Buffer = 256 (lenFLASH_LOG)
	//	LIMITE DA FLASH = 4096 bytes por cada setor
	//---------------------------------------------


// SETOR 15 da FLASH addr 0x0000f000
#define idFLASH  0x5a55a504
#define lenFLASH 512

// estrutura para salvar o log de erros
typedef struct {
	u32 countTick;
	u8 code; // valor 0 sem erro
} __attribute__ ((packed)) tDataLog;

typedef struct {
	u32 id;
	tParServo parServo[SERVO_N_MODULE];
	u16 crc;
} __attribute__ ((packed)) tDataFlash; // 	Especifica ao compilador para não alinhar a estrutura.

typedef struct {
	tDataLog err[nLOG];
	u16 crc;
} __attribute__ ((packed)) tLogFlash; // 	Especifica ao compilador para não alinhar a estrutura.

// ###############################################################################
// CONTROL
typedef struct {
} tJoy;
typedef struct {
	volatile uint ticks;
	volatile char key;	// Valor do teclado pressionado
	tDataLog err[nLOG];
	tRelay relay1;
	tRelay relay2;
	tServos servo[SERVO_N_MODULE];
	volatile tJoy joyServo[SERVO_N_MODULE];
} tControl, *pControl;
tControl control;

void showVicError(int n);

void servo_Init(void);
int servo_Config(uint servo, uint init, uint min, uint max, int offset, int tp, int toff);
int servo_Offset(uint servo, int offset);
int servo_SetPos(uint servo, uint us);
void servo_Parking(void);
void servo_Hand(int act);
	#define handOPEN 0
	#define handCLOSE 1
void servo_Tick(void);

void relay_Init(void);
void relay_Tick(void);
int relay_Set(int rly, int st, uint timeout);

void onKeyDown(char key);
void onKeyPress(char key);
void onKeyUp(char key);

void app_Init(void);
void app_Tick(void);
void app_Process(void);

int check_Values(void);
void par_ValuesDefaults(void);
void flash_Load(void);
int flash_Save(void);
int flash_ClearLogError(void);
int flash_SaveLogError(u32 countTicks, u8 n);

void prompt_Process(void);

#endif
